package com.suisui.asymmetric;

import com.suisui.util.HexUtils;

import java.security.PrivateKey;
import java.security.Signature;

public class RSATest2 {
    /**
     * 数字签名
     * 发送方A：原始内容--通过摘要算法获取原始内容的摘要str1-->把str1用发送方的私钥加密-->数字签名
     * 接收方B：用发送方的公钥验证签名并解密-->对原始内容进行摘要算法str2-->比较str1==str2(保证未被篡改)
     *注意：不是用公钥加密hash，如果用公钥，别人没私钥，无法验证
     * 因为签名是先进行摘要再进行rsa，所以在摘要算法一定的情况下，签名后得到的字符串长度总是一样的
     * 目的：验证发送方就是发送方，校验完整性
     *
     * 数字信封：对称加密的密钥(分发不安全)-->接收放的rsa公钥加密-->接受方用rsa私钥再解开
     * 为什么分发密钥，不是约定好了吗？密钥会随着每个零件的数据一起发送给接收方
     *
     * 数字证书：有了数字签名就可以证明发送者的身份了，还有问题吗？
     * A:B这里存储的A的公钥被换成了C的公钥，A发送的信息也换了C的私钥生成的签名，现在需要一种手段来证明”B这里存储的A的公钥“就是A的公钥
     */

    //字符编码
    private static final String SIGNATURE_ALGORITHM = "SHA256WITHRSA";

    public static void main(String[] args) throws Exception {
        String content ="今晚八点，行动！";
        byte[] contentBytes = content.getBytes();
        String sign = sign(contentBytes);
        System.out.println("签名：" + sign);
        boolean status = verify(contentBytes,sign);
        System.out.println("验证结果：\r" + status);
    }

    private static boolean verify(byte[] data, String sign) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(new RSATest().getPublicKey());
        signature.update(data);
        return signature.verify(HexUtils.convertHex2Bytes(sign));
    }

    /**
     * 对信息使用私钥生成数字签名
     * @param data 原始数据
     * @return
     */
    private static String sign(byte[] data) throws Exception {
        //获取签名对象
        PrivateKey privateKey = new RSATest().getPrivateKey();
        //用指定的算法初始化签名对象：先进行摘要再进行加密
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data);
        return HexUtils.convertBytes2HexStr(signature.sign());
    }
}
